/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_httpd.htm
 *
 * Zhiqim Httpd is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.httpd.entities;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import org.zhiqim.httpd.HttpContext;
import org.zhiqim.httpd.HttpEntity;
import org.zhiqim.httpd.HttpHeader;
import org.zhiqim.httpd.HttpSender;
import org.zhiqim.httpd.constants.HttpMimeType;

import org.zhiqim.kernel.util.DateTimes;
import org.zhiqim.kernel.util.Files;
import org.zhiqim.kernel.util.Streams;
import org.zhiqim.kernel.util.Urls;

/**
 * 文件资源处理器
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
public class FileResourceEntity implements HttpEntity
{
    @Override
    public boolean isMatch(String pathInContext)
    {//全匹配，在handle中处理
        return true;
    }
    
    @Override
    public void handle(HttpHeader header, HttpSender sender) throws IOException
    {
        HttpContext context = header.getContext();
        String filePath = header.getPathOnResource();
        if (filePath == null)
        {
            filePath = context.getResourcePath() + header.getPathInContext();
            filePath = Urls.decode(filePath, header.getCharacterEncoding());
        }
        
        File file = new File(filePath);
        if (!file.exists() || !file.isFile())
        {
            context.getNotFoundHandler().handle(header, sender);
            return;
        }
        
        if (file.isHidden() || !file.canRead())
        {
            sender.sendError(_403_FORBIDDEN_);
            return;
        }
        
        String fileExt = Files.getFileExt(filePath);
        String mimeType = header.getMimeType();
        if (mimeType == null)
            mimeType = HttpMimeType.getResourceMimeType(fileExt);
        
        if (_TEXT_HTML_.equals(mimeType))
            sender.setContentType(_TEXT_HTML_+"; charset="+header.getCharacterEncoding());
        else
            sender.setContentType(mimeType);
        
        long lastModified = file.lastModified();
        String lastModifiedTime = DateTimes.getDateTimeHttp(lastModified);
        String ifModifiedSince = header.getHeader(_IF_MODIFIED_SINCE_);
        if (ifModifiedSince != null && ifModifiedSince.indexOf(lastModifiedTime) != -1)
        {//时间相等
            sender.setHeader(_CACHE_CONTROL_, _MAX_AGE_+"="+context.getExpires());
            sender.sendError(_304_NOT_MODIFIED_);
            return;
        }
        
        sender.setHeader(_ACCEPT_RANGES_, _BYTES_);
        sender.setHeader(_LAST_MODIFIED_, lastModifiedTime);
        
        if (header.isMethodResponseContent())
        {
            sender.setHeader(_CACHE_CONTROL_, _MAX_AGE_+"="+context.getExpires());
            sender.setHeader(_CONTENT_LENGTH_, file.length());
            try(FileInputStream fis = new FileInputStream(file))
            {
                Streams.putBytes(fis, sender.getOutputStream());
            }
        }
    }
}
